package tliasweb.aspect;

import com.alibaba.fastjson2.JSON;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tliasweb.Constants;
import tliasweb.anno.MyLog;
import tliasweb.entity.OperateLog;
import tliasweb.service.OperateLogService;
import util.JwtUtils;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

@Slf4j
@Component
@Aspect
public class LogAspect {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private OperateLogService logService;

    @Around("@annotation(mylog)")
    public Object around(ProceedingJoinPoint pjp, MyLog mylog) throws Throwable {
        log.info(pjp.toLongString());

        // 获取请求的另一种方式
//        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
//        HttpServletRequest request1 = requestAttributes.getRequest();
        // 从请求头中获取token
        String token = request.getHeader(Constants.TOKEN);
        // 解析token
        Claims claims = JwtUtils.parseJWT(token);
        // 从token中获取用户的id
        Integer userId = claims.get(Constants.ID, Integer.class);
        // 业务方法的方法签名
        Signature signature = pjp.getSignature();
        // 类名
        String className = signature.getDeclaringTypeName();
        // 方法名
        String methodName = signature.getName();
        // 方法的参数
        Object[] args = pjp.getArgs();
        // 开始时间
        long start = System.currentTimeMillis();
        // 继续执行业务逻辑，获取了返回值
        Object result = pjp.proceed();
        // 开结束时间
        long end = System.currentTimeMillis();
        // 构造数据库中的entity数据
        OperateLog log = new OperateLog();
        log.setOperateUser(userId);
        log.setOperateTime(LocalDateTime.now());
        log.setClassName(className);
        log.setMethodName(methodName);
        log.setMethodParams(args==null?"":JSON.toJSONString(args));
        log.setReturnValue(JSON.toJSONString(result));
        log.setCostTime((end-start));
        // 日志信息保存到数据库，异步记录数据库，1）响应时间 2）异常
        new Thread(new Runnable() {
            @Override
            public void run() {
                logService.save(log);
            }
        }).start();
        return result;
    }

}
